React官网井字格游戏拓展实现(附完整源码和最终成果截图)

您所在的位置:网站首页 react 环境 React官网井字格游戏拓展实现(附完整源码和最终成果截图)

React官网井字格游戏拓展实现(附完整源码和最终成果截图)

#React官网井字格游戏拓展实现(附完整源码和最终成果截图)| 来源: 网络整理| 查看: 265

前提

需要先依据react官网教程编写出基础的井字格游戏。

拓展实现及说明

最后面会有全部的源代码。

1、在游戏历史记录列表显示每一步棋的坐标,格式为 (列号, 行号)

直接给history里的squres再添加一列,保存点击的i值,即第几个方格,再在moves里计算得出列号和行号。 改为10的长度 增加一列 加下标

ps: Math.trunc()方法是通过除去小数位来返回浮点数的整数部分

2、在历史记录列表中加粗显示当前选择的项目

给历史记录列表的按钮绑定一个动态样式即可。 加粗当前选择的记录

3、使用两个循环来渲染出棋盘的格子,而不是在代码里写死(hardcode)

双重for循环

4、添加一个可以升序或降序显示历史记录的按钮

定义一个排序标志,升序为true,降序false。然后通过这个标志来升序或降序显示history数组的内容即可。 降序或升序

5、每当有人获胜时,高亮显示连成一线的 3 颗棋子

需要修改原来的计算成功者的方法calculateWinner,返回连成一线的下标数组winnerList,board组件双重循环渲染squre组件时可根据这个winnerList传一个flag标志给squre组件,然后squre组件里如果这个flag标志为true就背景色改变,就OK了。 计算成功的方法 board组件里修改的内容,注意第一行一定要取返回值得第一项,否则会出现点击没反应的情况。 board组件修改 最后,square组件根据lightFlag标志,动态显示背景颜色就大功告成了! square组件修改

6、当无人获胜时,显示一个平局的消息

判断当前的square是否填满,如果填满了,且未胜利即平局。 增加平局描述

源码和最终成果截图 完整源码 import {useState} from 'react'; function Square({value,lightFlag, onSquareClick}) { return ( backgroundColor: lightFlag ? 'green' : 'transparent'}} className="square" onClick={onSquareClick}> {value} ); } function Board({xIsNext, squares, onPlay}) { function handleClick(i) { if (calculateWinner(squares)[0] || squares[i]) { return; } const nextSquares = squares.slice(); if (xIsNext) { nextSquares[i] = 'X'; } else { nextSquares[i] = 'O'; } nextSquares[9] = i //增加一列记录下标,可通过计算转坐标 onPlay(nextSquares); } const [winner,winnerLine] = calculateWinner(squares); let status; if (winner) { status = '获胜的是: ' + winner; } else { if(!squares.includes(null)){ status='实力伯仲之间,平局' }else { status = '下一步棋手: ' + (xIsNext ? 'X' : 'O'); } } const numbers = [0, 1, 2] const listItems = numbers.map((number, rowIndex) => { return ( numbers.map((item, columnIndex) => { let lightFlag=winnerLine.includes(rowIndex * 3 + columnIndex) return renderSquare(rowIndex * 3 + columnIndex,lightFlag) }) } ) }) //生成方格 function renderSquare(i,lightFlag) { return ( squares[i]} lightFlag={lightFlag} onSquareClick={() => handleClick(i)}/> ); } return ( {status} {listItems} {/**/} {/* handleClick(0)} />*/} {/* handleClick(1)} />*/} {/* handleClick(2)} />*/} {/**/} {/**/} {/* handleClick(3)} />*/} {/* handleClick(4)} />*/} {/* handleClick(5)} />*/} {/**/} {/**/} {/* handleClick(6)} />*/} {/* handleClick(7)} />*/} {/* handleClick(8)} />*/} {/**/} ); } export default function Game() { const [history, setHistory] = useState([Array(10).fill(null)]); const [currentMove, setCurrentMove] = useState(0); const [sortReverseFlag,setSortReverseFlag]=useState(true); //排序标志 const xIsNext = currentMove % 2 === 0; const currentSquares = history[currentMove]; function handlePlay(nextSquares) { const nextHistory = [...history.slice(0, currentMove + 1), nextSquares]; setHistory(nextHistory); setCurrentMove(nextHistory.length - 1); } function jumpTo(nextMove) { setCurrentMove(nextMove); } const moves = history.map((squares, move) => { let description; move=sortReverseFlag?move:history.length-move-1 if (move > 0) { description = '跳到第' + move + '步,坐标(' + Math.trunc(squares[9] / 3 + 1) + ',' + (squares[9] % 3 + 1) + ')' +",下棋者:"+ (move%2 ?'X':'O'); } else { description = '重新开始游戏'; } return ( {fontWeight: (move === currentMove) ? 'bold' : 'normal'}} onClick={() => jumpTo(move)}> {description} ); }); return ( currentSquares} onPlay={handlePlay}/> sortReverseFlag ? '升序' : '降序'} {moves} ); } function calculateWinner(squares) { const lines = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; for (let i = 0; i return [squares[a],lines[i]]; } } return [null,[]]; } 最终成果截图

获胜截图: 胜利 倒序截图: 历史记录倒序



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3